// 用 apply 调用函数 并 指定函数内部 this 指向的实例

// 采用"函数声明"方式定义函数
function welcome(nickname){
    console.log(`热烈欢迎${nickname}来到开发喵`);
}

// 通过函数名来调用函数
welcome( '阿芳' );

// 通过 apply 来调用函数
// Function.prototype.apply( thisArg [, paramArray] )
welcome.apply( null, ['小芳'] );

console.log( '- '.repeat(20) );

// 在 Node.js 环境中 globalThis 指向 global
globalThis.name = '李小芳';

// 采用"函数声明"方式定义函数
function introduce(){
    console.log( this === globalThis );
    console.log(`大家好，我是${this.name}`);
}

// 直接用函数名调用函数时，函数内部的 `this` 指向 `global object`
introduce();
// 通过apply调用函数时，若apply首个参数为 null 或 undefined 或 未显式指定，
// 则函数内部的 `this` 指向 `global object`
introduce.apply( null );
introduce.apply( undefined );
introduce.apply();

const x = { name: '赵德芳' }
// 将 x 作为参数传递给 apply 函数，
// 则在调用 introduce 函数时，其内部的 this 就指向了 x 对应的实例
introduce.apply( x );

console.log( '- '.repeat(20) );

const instance = {
    name: '菲尔娜',
    fly(){
        console.log( this === instance );
        console.log(`${this.name}飞起来了`);
    }
}

// 通过定义方法的实例调用方法时，方法内部的this指向定义该方法的实例
instance.fly();

// 通过 apply 调用 instance.fly 方法时，
// 为 apply 函数传入的第一个参数就是 instance.fly 方法内部this指向的实例
instance.fly.apply(x);

// 参考文档:
// https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/call